﻿/*

	使用本script的先決條件是必須引入json2.js，除非網頁只打算給IE8開。

	引用本程式後即可擁有以下類別與物件:

	[class]
	DOMParser 
		parseFromString()

	Ajax
		get()
		set()
		callCSharpService()

	[static]
		UnicodeParser
		encode()
		decode()
*/
//建立類別，可以在需要的時候才製作實體，並可避免各實體之間的互相干擾。
function Ajax(){
	var xmlHttp = null;
	var onCompleteCallback = null;
	var onTimeoutCallback = null;
	var onErrorCallback = null;
	var xmlHttpTimeout = null; 
	var defaultTimeout = 5000;
	var createXMLHttpRequest = function () {
		if (xmlHttp == null){
			if (window.XMLHttpRequest) {
				xmlHttp = new XMLHttpRequest();
				//xmlHttp.overrideMimeType('text/xml'); // firefox
				//因為IE8也支援window.XMLHttpRequest，所以這一行不能用了
			}else if (window.ActiveXObject) {
				xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
	}
	this.get = function(_url, _options){
		return this.run('GET', _url, _options);
	}
	this.post = function(_url, _options){
		return this.run('POST', _url, _options);
	}
	this.getXML = function(_url, _options){
		_options.parser = function (data){
			return new DOMParser().parseFromString(xmlString,'text/xml');
		}
		return this.run('GET', _url, _options);
	}


	this.run = function(_method, _url, _options){
		//createXMLHttpRequest();
		if (window.XMLHttpRequest) {
			xmlHttp = new XMLHttpRequest();

			//因為IE8也支援window.XMLHttpRequest了，所以這一行不能用了
			//xmlHttp.overrideMimeType('text/xml'); // firefox only

		}else if (window.ActiveXObject) {
			xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
		}

		if(!xmlHttp) {
			alert("The XMLHttpRequest not supported");
			return;
		}
		onCompleteCallback = _options.onComplete;
		onTimeoutCallback = _options.onTimeout;
		onErrorCallback = _options.onError;
		var timeoutMS = _options.timeout || defaultTimeout;
		// IE8 natively supports xmlHttp.ontimeout event, don't know if other browsers can do?
		xmlHttpTimeout = setTimeout(function (){
		   xmlHttp.abort();
		   if (typeof(onTimeoutCallback) == 'function') onTimeoutCallback();
		}, timeoutMS);
		
		/* readyState 所有可能的值如下：
    * 0 (還沒開始)
    * 1 (讀取中)
    * 2 (已讀取)
    * 3 (資訊交換中)
    * 4 (一切完成) 
		*/
		var dataParser = _options.parser;
		xmlHttp.onreadystatechange = function () {
			if (xmlHttp.readyState == 4) {
				if(xmlHttpTimeout!=null) clearTimeout(xmlHttpTimeout);
				if (xmlHttp.status == 200) {
					if (typeof(onCompleteCallback) == 'function'){
						var response = xmlHttp.responseText;
						if (typeof(dataParser)=='function') response = dataParser(response);
						onCompleteCallback(response);
					}
				}else{
					if (typeof(onErrorCallback) == 'function') onErrorCallback(xmlHttp.status);
				}
			}
		};
		var parameterString = '';//據說在IIS6不能傳null，但我在IIS7 post時也沒辦法傳null
		var parameterLength = 0;
		if (_options.parameters){
			var parameters = [];
			for (var k in _options.parameters){
				if (parameters.length>0) parameters.push('&');
				parameters.push(k);
				parameters.push('=');
				parameters.push(encodeURI(_options.parameters[k]));
			}
			parameterString = parameters.join('');
			parameterLength = parameterString.length;
		}

		xmlHttp.open(_method, _url, true);//(httpMethod,  URL,  asynchronous)

		if (_method.toLowerCase() == 'post'){
			// set the necessary request headers
			xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
			xmlHttp.setRequestHeader("Content-Length", parameterLength);
			xmlHttp.setRequestHeader("Connection", "close");  
		}else if (_method.toLowerCase() == 'get'){
			if (parameterString.length>0) _url += parameterString;
		}
		//alert(parameterString);
		
		xmlHttp.send(parameterString);
		
	}

}


var UnicodeParser = {
	encode: function(str) {
		var a = [],
		i = 0;
		for (; i < str.length; ) a[i] = ("00" + str.charCodeAt(i++).toString(16)).slice(-4);
		return "\\u" + a.join("\\u")
	},
	decode: function(str) {
		return unescape(str.replace(/\\/g, "%"))
	}
};

/*
呼叫的時候用new敘述產生新的instance:

new Ajax().get('text2.txt', {
	onComplete: function(returnData){
		document.getElementById('textarea1').value += returnData;
	}
	,onErrorCallback: function(){}
	,onTimeoutCallback: function(HTTPStatus){}
	}
);

*/
/*
Date.prototype.toJSON = function(){
	return 'new Date('+this.getTime()+')';
}
*/
